home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 399_01 / minedio.c < prev    next >
C/C++ Source or Header  |  1993-08-03  |  28KB  |  1,329 lines

  1. /*  ==================================================================    *
  2.  *                Editor mined                *
  3.  *            Operating system dependant I/O            *
  4.  *  ==================================================================    */
  5.  
  6. #include "mined.h"
  7. #include <errno.h>
  8. #include <signal.h>
  9.  
  10. #ifdef CURSES
  11. #include <curses.h>
  12. #undef FALSE
  13. #undef TRUE
  14. #undef TERMIO    /* \ must be  */
  15. #undef SGTTY    /* / disabled */
  16. #endif
  17.  
  18. #ifdef TERMIO
  19. #include <termios.h>
  20. #endif
  21. #ifdef SGTTY
  22. #include <sys/ioctl.h>    /* <sgtty.h> ? */
  23. extern void ioctl ();
  24. #endif
  25.  
  26. #ifdef SIGPHONE        /* this trick was taken from less' screen.c */
  27. #include <sys/window.h>    /* for window size detection */
  28. #endif
  29.  
  30. #ifdef msdos
  31. #define _getch_
  32. #include <dos.h>
  33. #endif
  34.  
  35. #ifdef unix
  36. #include <sys/time.h>    /* for struct timeval (for select in inputreadyafter) */
  37. #define selectread    /* use select () ? */
  38. #endif
  39.  
  40. #ifdef vms
  41. #include <socket.h>    /* for select () and struct timeval */
  42. # ifdef CURSES
  43. # define _getch_
  44. # endif
  45. #endif
  46.  
  47. #ifdef _getch_
  48. #ifndef CURSES
  49. extern int getch ();
  50. #endif
  51. #endif
  52.  
  53. /*  ==================================================================    *
  54.  *            Unix signalling routines            *
  55.  *  ==================================================================    */
  56.  
  57. void
  58. catch_signals (catch)
  59.   void (* catch) ();
  60. {
  61. #ifdef SIGHUP
  62.   signal (SIGHUP, catch);
  63. #endif
  64. #ifdef SIGILL
  65.   signal (SIGILL, catch);
  66. #endif
  67. #ifdef SIGTRAP
  68.   signal (SIGTRAP, catch);
  69. #endif
  70. #ifdef SIGABRT
  71.   signal (SIGABRT, catch);
  72. #endif
  73. #ifdef SIGEMT
  74.   signal (SIGEMT, catch);
  75. #endif
  76. #ifdef SIGFPE
  77.   signal (SIGFPE, catch);
  78. #endif
  79. #ifdef SIGBUS
  80.   signal (SIGBUS, catch);
  81. #endif
  82. #ifdef SIGSEGV
  83.   signal (SIGSEGV, catch);
  84. #endif
  85. #ifdef SIGSYS
  86.   signal (SIGSYS, catch);
  87. #endif
  88. #ifdef SIGPIPE
  89.   signal (SIGPIPE, catch);
  90. #endif
  91. #ifdef SIGALRM
  92.   signal (SIGALRM, catch);
  93. #endif
  94. #ifdef SIGTERM
  95.   signal (SIGTERM, catch);
  96. #endif
  97. #ifdef SIGXCPU
  98.   signal (SIGXCPU, catch);
  99. #endif
  100. #ifdef SIGXFSZ
  101.   signal (SIGXFSZ, catch);
  102. #endif
  103. #ifdef SIGVTALRM
  104.   signal (SIGVTALRM, catch);
  105. #endif
  106. #ifdef SIGPROF
  107.   signal (SIGPROF, catch);
  108. #endif
  109. #ifdef SIGLOST
  110.   signal (SIGLOST, catch);
  111. #endif
  112. #ifdef SIGUSR1
  113.   signal (SIGUSR1, catch);
  114. #endif
  115. #ifdef SIGUSR2
  116.   signal (SIGUSR2, catch);
  117. #endif
  118. #ifdef SIGUSR3
  119.   signal (SIGUSR3, catch);
  120. #endif
  121. }
  122.  
  123. #ifdef SIGTSTP
  124. void
  125. suspendmyself ()
  126. {
  127.   kill (getpid (), SIGTSTP);
  128. }
  129. FLAG cansuspendmyself = TRUE;
  130. #else
  131. void
  132. suspendmyself ()
  133. {}
  134. FLAG cansuspendmyself = FALSE;
  135. #endif
  136.  
  137. #ifdef SIGWINCH
  138. /*
  139.  * Catch the SIGWINCH signal sent to mined.
  140.  */
  141. void
  142. catchwinch ()
  143. {
  144.   winchg = TRUE;
  145. /*  if (waitingforinput == TRUE) RDwin (); */
  146. /* This is now performed in __readchar () to prevent display garbage 
  147.    in case this interrupts occurs during display output operations which 
  148.    get screen size related values changed while relying on them. */
  149.   signal (SIGWINCH, catchwinch); /* Re-installation of the signal */
  150. }
  151. #endif
  152.  
  153. #ifdef SIGQUIT
  154. /*
  155.  * Catch the SIGQUIT signal (^\) sent to mined. It turns on the quitflag.
  156.  */
  157. void
  158. catchquit ()
  159. {
  160. #ifdef UNUSED /* Should not be needed with new __readchar () */
  161. /* Was previously needed on SUN but showed bad effects on Iris. */
  162.   static char quitchar = '\0';
  163.   if (waitingforinput == TRUE)
  164.     /* simulate input to enable immediate break also during input */
  165.     ioctl (input_fd, TIOCSTI, & quitchar);
  166. #endif
  167.   quit = TRUE;
  168.   signal (SIGQUIT, catchquit); /* Re-installation of the signal */
  169. }
  170. #endif
  171.  
  172. #ifdef SIGBREAK
  173. /*
  174.  * Catch the SIGBREAK signal (control-Break) and turn on the quitflag.
  175.  */
  176. void
  177. catchbreak ()
  178. {
  179.   quit = TRUE;
  180.   signal (SIGBREAK, catchbreak); /* do we need this ? */
  181. }
  182. #else
  183. # ifdef msdos
  184. int
  185. controlbreak ()
  186. {
  187.   quit = TRUE;
  188.   return 1 /* continue program execution */;
  189. }
  190. # endif
  191. #endif
  192.  
  193. #ifdef SIGINT
  194. /*
  195.  * Catch the SIGINT signal (^C) sent if it cannot be ignored by tty driver
  196.  */
  197. void
  198. catchint ()
  199. {
  200.   intr_char = TRUE;
  201.   signal (SIGINT, catchint); /* Re-installation of the signal */
  202. }
  203. #endif
  204.  
  205. /*  ==================================================================    *
  206.  *            Terminal mode switcher                *
  207.  *  ==================================================================    */
  208.  
  209. /*
  210.  * Set and reset tty into CBREAK or old mode according to argument `state'.
  211.  * It also sets all signal characters (except for ^\) to UNDEF. ^\ is caught.
  212.  */
  213. void
  214. raw_mode (state)
  215.   FLAG state;
  216. {
  217. #ifdef TERMIO
  218.   static struct termios old_termio;
  219.      struct termios new_termio;
  220. #ifdef TCGETS
  221. # define gettermio(fd, iopoi)    ioctl (fd, TCGETS, iopoi);
  222. # ifdef TCSETSW
  223. # define settermio(fd, iopoi)    ioctl (fd, TCSETSW, iopoi);
  224. # else
  225. # define settermio(fd, iopoi)    ioctl (fd, TCSETS, iopoi);
  226. # endif
  227. #else
  228. # define gettermio(fd, iopoi)    tcgetattr (fd, iopoi);
  229. # ifdef TCSADRAIN
  230. # define settermio(fd, iopoi)    tcsetattr (fd, TCSADRAIN, iopoi);
  231. # else
  232. # define settermio(fd, iopoi)    tcsetattr (fd, 0, iopoi);
  233. # endif
  234. #endif
  235. #endif /* TERMIO */
  236.  
  237. #ifdef SGTTY
  238.   static struct sgttyb old_tty;
  239.      struct sgttyb new_tty;
  240.   static int oldlmode;
  241.      int lmode;
  242.   static struct tchars old_tchars;
  243.   static struct ltchars old_ltchars;
  244. #define NDEF '\377'
  245.   static struct tchars new_tchars = {NDEF, QUITCHAR, NDEF, NDEF, NDEF, NDEF};
  246.   static struct tchars new_QStchars = {NDEF, QUITCHAR, '\021', '\023', NDEF, NDEF};
  247.   static struct ltchars new_ltchars = {NDEF, NDEF, NDEF, NDEF, NDEF, NDEF};
  248. /* correspondence between the tchars/ltchars characters of the sgtty 
  249.    interface and the c_cc characters of the termios interface (codes vary):
  250.     sgtty        termio        sgtty        termio
  251.     t_intrc        VINTR        t_suspc        VSUSP
  252.     t_quitc        VQUIT        t_dsuspc    VDSUSP
  253.     t_startc    VSTART        t_rprntc    VREPRINT
  254.     t_stopc        VSTOP        t_flushc    VDISCARD
  255.     t_eofc        VEOF (VMIN)    t_werasc    VWERASE
  256.     t_brkc        VEOL (VTIME)    t_lnextc    VLNEXT
  257. */
  258. #endif /* SGTTY */
  259.  
  260.   if (state == OFF) {
  261.     isscreenmode = FALSE;
  262. #ifdef CURSES
  263.     endwin ();
  264. #ifdef vms
  265.     system ("set terminal /ttsync /nopasthru");
  266. #endif
  267. #else /* ndef CURSES: */
  268.     end_screen_mode ();
  269.     flush ();
  270. #endif /* ndef CURSES */
  271.  
  272. #ifdef TERMIO
  273.     settermio (input_fd, & old_termio);
  274. #endif
  275. #ifdef SGTTY
  276.     ioctl (input_fd, TIOCSETP, & old_tty);
  277.     ioctl (input_fd, TIOCSETC, & old_tchars);
  278.     ioctl (input_fd, TIOCSLTC, & old_ltchars);
  279.     ioctl (input_fd, TIOCLSET, & oldlmode);
  280. #endif
  281.     return;
  282.   }
  283.  
  284.   else /* (state == ON) */ {
  285.     isscreenmode = TRUE;
  286. #ifdef CURSES
  287.     refresh ();
  288. #else
  289.     start_screen_mode ();
  290.     flush ();
  291. #endif
  292. #ifdef TERMIO
  293.     gettermio (input_fd, & old_termio);
  294.     gettermio (input_fd, & new_termio);
  295.  
  296.     if (controlQS == FALSE)
  297.       new_termio.c_iflag &= ~(ISTRIP|IXON|IXOFF);
  298.     else
  299.       new_termio.c_iflag &= ~(ISTRIP);
  300.     new_termio.c_oflag &= ~OPOST;
  301.     new_termio.c_cflag &= ~(PARENB|CSIZE);
  302.     new_termio.c_cflag |= CS8;
  303.     new_termio.c_lflag &= ~(ICANON|ECHO);
  304. #define NDEF '\000'
  305.     new_termio.c_cc [VMIN] = 1;
  306.     new_termio.c_cc [VTIME] = 0;
  307.     new_termio.c_cc [VQUIT] = QUITCHAR;
  308.     new_termio.c_cc [VINTR] = NDEF;
  309.     new_termio.c_cc [VSUSP] = NDEF;
  310. #ifdef VDISCARD
  311.     new_termio.c_cc [VDISCARD] = NDEF;
  312. #endif
  313.     settermio (input_fd, & new_termio);
  314. #endif /* TERMIO */
  315. #ifdef SGTTY
  316. /* Save old tty settings */
  317.     ioctl (input_fd, TIOCGETP, & old_tty);
  318.     ioctl (input_fd, TIOCGETC, & old_tchars);
  319.     ioctl (input_fd, TIOCGLTC, & old_ltchars);
  320.     ioctl (input_fd, TIOCLGET, & oldlmode);
  321. /* Set line mode */
  322. /* If this feature should not be available on some system, RAW must be used
  323.    instead of CBREAK below to enable 8 bit characters on output */
  324.     lmode = oldlmode;
  325.     lmode |= LPASS8; /* enable 8 bit characters on input in CBREAK mode */
  326.     lmode |= LLITOUT; /* enable 8 bit characters on output in CBREAK mode;
  327.         this may not be necessary in newer Unixes, e.g. SUN-OS 4;
  328.         output handling is slightly complicated by LITOUT */
  329.     ioctl (input_fd, TIOCLSET, & lmode);
  330. /* Set tty to CBREAK (or RAW) mode */
  331.     new_tty = old_tty;
  332.     new_tty.sg_flags &= ~ECHO;
  333.     new_tty.sg_flags |= CBREAK;
  334.     ioctl (input_fd, TIOCSETP, & new_tty);
  335. /* Unset signal chars */
  336.     if (controlQS == FALSE)
  337.       ioctl (input_fd, TIOCSETC, & new_tchars);  /* Only leaves QUITCHAR */
  338.     else
  339.       ioctl (input_fd, TIOCSETC, & new_QStchars);  /* Leaves QUITCHAR, ^Q, ^S */
  340.     ioctl (input_fd, TIOCSLTC, & new_ltchars); /* Leaves nothing */
  341. #endif /* SGTTY */
  342.  
  343. /* Define signal handlers */
  344. #ifdef SIGQUIT
  345.     signal (SIGQUIT, catchquit);    /* Catch QUITCHAR (^\) */
  346. #endif
  347. #ifdef SIGBREAK
  348.     signal (SIGBREAK, catchbreak);    /* contro